using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using TreeView.Logic;
using TreeView.Graphic;
using System.Collections;
using Gui;
using Data.DataTranslator;

namespace WindowsApplication2.TreeView.Graphic
{
    public partial class TreeView : UserControl
    {
        #region Members

        private RadialTree dispTree;
        private RadialTree originalTree;
        private ArrayList guiTreeNodes;
        private Brush selectedNodeColor;
        
        #endregion

        #region Constructors

        public TreeView()
        {
            InitializeComponent();
            selectedNodeColor = Brushes.White;
        }

        #endregion

        #region Methods

        private void btn_ResetTree_Click(object sender, EventArgs e)
        {
            if (dispTree != null)
            {
                lbl_SpreadAngle.Text = ((int)(originalTree.Teta * 180)).ToString();
                hsb_SpreadAngle.Value = ((int)(originalTree.Teta * 180));
                dispTree = originalTree;
                dispTree.createGUIRadTree(originalTree.TreeNodes, Pnl_TreeShow.Width, Pnl_TreeShow.Height);
                ApplyTreeChange();
                Pnl_TreeShow.Refresh();
            }
        }

        private void Pnl_TreeShow_MouseClick(object sender, MouseEventArgs e)
        {
            if (dispTree != null)
            {
                double spreadAngle = (Double.Parse(lbl_SpreadAngle.Text)) / 180;
                if (spreadAngle > 2)
                    spreadAngle = 2;
                RadNodeGUI foundNode = findContain(e.X, e.Y);
                if (foundNode != null)
                    onMousClick(spreadAngle, foundNode, dispTree, e);
            }
        }

        private void Pnl_TreeShow_MouseMove(object sender, MouseEventArgs e)
        {
            if (dispTree != null)
            {
                RadNodeGUI foundNode = findContain(e.X, e.Y);
                if (foundNode != null)
                    onMousMove(foundNode, e);
            }
        }

        private void Pnl_TreeShow_Paint(object sender, PaintEventArgs e)
        {
            if ((dispTree != null) && (dispTree.TreeNodes.Count != 0))
            {
                Graphics g = e.Graphics;
                //Graphics g = Pnl_TreeShow.CreateGraphics();
                g.FillEllipse(Brushes.Black, 0, 0, Pnl_TreeShow.Width, Pnl_TreeShow.Height);
                //if we don't have nodes ready to print
                if (guiTreeNodes == null)
                {
                    dispTree.createGUIRadTree(originalTree.TreeNodes, Pnl_TreeShow.Width, Pnl_TreeShow.Height);
                    ApplyTreeChange();
                }
                //go over the tree and print all the nodes
                printTree(e);                
            }
        }

        /// <summary>
        /// The run botton of the agglomerative algorithm
        /// </summary>
        public void EnableResultView(string spreadAngle, RadialTree treeData)
        {
            int angle = Int32.Parse(spreadAngle);
            originalTree = treeData;
            originalTree.createGUIRadTree(originalTree.TreeNodes, Pnl_TreeShow.Width, Pnl_TreeShow.Height);
            dispTree = originalTree;
            ApplyTreeChange();
            Pnl_TreeShow.Refresh();
            Pnl_TreeShow.Visible = true;
            pnl_Options.Visible = true;
            this.lbl_TreeResErr.Visible = false;
            this.lbl_SpreadAngle.Text = spreadAngle;
            this.hsb_SpreadAngle.Value = (int)(dispTree.Teta * 180);
        }

        public void makeColorTree(int property)
        {
            dispTree.createGUIRadTree(dispTree.TreeNodes, Pnl_TreeShow.Width, Pnl_TreeShow.Height, property);

            ApplyTreeChange();
            Pnl_TreeShow.Refresh();
        }

        private void ApplyTreeChange()
        {
            guiTreeNodes = new ArrayList();
            foreach (RadialTreeNode node in dispTree.TreeNodes)
                guiTreeNodes.Add(node.NodeGUI);
            Pnl_TreeShow.Refresh();
        }

        public void printTree(PaintEventArgs e)
        {
            foreach (RadNodeGUI node in guiTreeNodes)
            {
                node.paintNode(e.Graphics);
            }
            foreach (RadNodeGUI node in guiTreeNodes)
            {
                node.paintBody(e.Graphics);
            }
        }

        
                    //float leftRatio, rightRatio;
                    //leftRatio = LeftSon.Depth / (LeftSon.Depth + LeftSon.Hight);
                    //rightRatio = RightSon.Depth / (RightSon.Depth + RightSon.Hight);
                    //if (leftRatio < rightRatio)
                    //{
                    //    Father.LeftSon = LeftSon;
                    //    Father.RightSon = RightSon;
                    //}
                    //else
                    //{
                    //    Father.LeftSon = LeftSon;
                    //    Father.RightSon = RightSon;
                    //}
                    ////continue here

        private RadNodeGUI findContain(int x, int y)
        {
            try
            {
                RadNodeGUI FounNode = null;
                foreach (RadNodeGUI node in guiTreeNodes)
                {
                    if (node.NodeBody.Contains(x, y))
                        FounNode = node;
                    if (node.NodeBrush == selectedNodeColor)
                    {
                        node.resetBrush();
                        node.paintBody(Pnl_TreeShow);
                    }
                }
                return FounNode;
            }
            catch (NullReferenceException)
            {
                MessageBox.Show("The tree is empty", "Error!!!");
                return null;
            }
        }

        private void onMousMove(RadNodeGUI node, MouseEventArgs e)
        {
            if (node != null)
            {
                Cursor.Current = Cursors.Hand;
                node.NodeBrush = selectedNodeColor;
                node.paintBody(Pnl_TreeShow);
                if (node.LogicNode.isLeaf())
                {
                    tipName.SetToolTip(Pnl_TreeShow, node.LogicNode.Name);
                    PieProperties.Visible = false;
                }
                else
                {
                    tipTreeHlp.SetToolTip(Pnl_TreeShow, "click me to see my sub tree");
                    //here need to change to the porperties names from moran.
                    ArrayList[] clusterDistribution = new ArrayList[2];
                    clusterDistribution = kDimMap.getPropertiesDivisionOfCluster(node.LogicNode.SonsCodeNames, (int)nud_DistFeatureNum.Value - 1);
                    ArrayList propNames = (ArrayList)clusterDistribution[1];

                    //here we need to get the amount of genome in each of the properties
                    ArrayList propValue = (ArrayList)clusterDistribution[0];


                    //Series initialization
                    PieProperties.Series.Clear();
                    Dundas.Charting.WinControl.Series clusterSeries = new Dundas.Charting.WinControl.Series();
                    //clusterSeries.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
                    clusterSeries.ChartType = "Pie";
                    clusterSeries.CustomAttributes = "PieLabelStyle=Inside";
                    clusterSeries.Name = "clusterDistribution";
                    clusterSeries.ShadowOffset = 2;
                    clusterSeries.ShowLabelAsValue = true;
                    clusterSeries.ShowInLegend = true;

                    for (int i = 0; i < propValue.Count; i++)
                    {
                        double[] data = new double[1];
                        data[0] = (double)propValue[i];
                        Dundas.Charting.WinControl.DataPoint PropValue = new Dundas.Charting.WinControl.DataPoint();
                        PropValue.LegendText = (string)propNames[i];//this shuld be shorter name
                        PropValue.LegendText = PropValue.LegendText.Substring(0, 4);
                        PropValue.LegendToolTip = (string)propNames[i];
                        PropValue.XValue = (double)i;
                        PropValue.YValues = data;
                        clusterSeries.Points.Add(PropValue);
                    }
                    PieProperties.Series.Add(clusterSeries);
                    PieProperties.Visible = true;
                }
            }
        }

        private void onMousClick(double newTeta, RadNodeGUI foundNode, RadialTree DispTree, MouseEventArgs e)
        {
            if (foundNode != null)
            {
                dispTree = dispTree.SubRadialTree(foundNode.LogicNode, newTeta);
                dispTree.createGUIRadTree(dispTree.TreeNodes, Pnl_TreeShow.Width, Pnl_TreeShow.Height);
                ApplyTreeChange();
                Pnl_TreeShow.Refresh();
            }
        }

        private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            lbl_SpreadAngle.Text = hsb_SpreadAngle.Value.ToString();
        }

        private void btn_Newick_Click(object sender, EventArgs e)
        {
            string sNewick = ((RadialTreeNode)originalTree.TreeNodes[originalTree.TreeNodes.Count - 1]).ToString();
        }

        private void btn_SaveTree_Click(object sender, EventArgs e)
        {
            ArrayList t = originalTree.RadTree2MergList();
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton2.Checked == true)
                makeColorTree((int)nud_ColorFeatureNum.Value);
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (rbtn_Clusters.Checked == true)
                makeColorTree(-1);
        }

        #endregion

        private void hsb_SpreadAngle_MouseCaptureChanged(object sender, EventArgs e)
        {
            if ((dispTree != null) && (hsb_SpreadAngle.Capture == false))
            {
                double spreadAngle = (Double.Parse(lbl_SpreadAngle.Text)) / 180;
                if (spreadAngle > 2)
                    spreadAngle = 2;
                dispTree = dispTree.SubRadialTree(null, spreadAngle);
                dispTree.createGUIRadTree(dispTree.TreeNodes, Pnl_TreeShow.Width, Pnl_TreeShow.Height);
                if (radioButton2.Checked == true)
                    makeColorTree((int)nud_ColorFeatureNum.Value);
                else 
                    if (rbtn_Clusters.Checked == true)
                        makeColorTree(-1);
                ApplyTreeChange();
                Pnl_TreeShow.Refresh();
            }
        }

    }
}

//private static double HuetoRGB(double m1, double m2, double h)
//{
//    if (h < 0)
//    {
//        h = 1.0;
//    }
//    if (h > 1)
//    {
//        h = 1.0;
//    }
//    if (6.0 * h < 1)
//    {
//        return (m1 + (m2 - m1) * h * 6.0);
//    }
//    if (2.0 * h < 1)
//    {
//        return m2;
//    }
//    if (3.0 * h < 2.0)
//    {
//        return (m1 + (m2 - m1) * ((2.0 / 3.0) - h) * 6.0);
//    }
//    return m1;
//}
///**
// * Converte an HLS color to RGB color
// * 
// * @example <listing version="3.0">
// * 
// * ColorUtils.HLStoRGB(34,3,23);
// * 
// * </listing>
// * 
// * @param h Hue value 
// * @param l Luminance value
// * @param s Saturation value
// *
// * @return an integer that represents an RGB color.
// */
//public static Color HLStoRGB2(double H, double L, double S)
//{
//    int r, g, b;
//    double TempR, TempG, TempB, m1, m2;

//    if (S == 0)
//    {
//        TempR = TempG = TempB = L;
//    }
//    else
//    {
//        if (L <= 0.5)
//        {
//            m2 = L * (1.0 + S);
//        }
//        else
//        {
//            m2 = L + S - L * S;
//        }
//        m1 = 2.0 * L - m2;
//        TempR = HuetoRGB(m1, m2, H + 1.0 / 3.0);
//        TempG = HuetoRGB(m1, m2, H);
//        TempB = HuetoRGB(m1, m2, H - 1.0 / 3.0);
//    }
//    r = (int)(TempR * 255) % 255;
//    g = (int)(TempG * 255) % 255;
//    b = (int)(TempB * 255) % 255;
//    return Color.FromArgb(r, g, b);
//}